﻿#region LICENSE
/****************************************************************************
 *                                                                          *
 *  CoderBlu.Collections - Thread-safe Collections                          *
 *  Copyright (C) 2008 Rodger "Nullz" Aiken <nullz.void@gmail.com>          *
 *                                                                          *
 *  This library is free software; you can redistribute it and/or modify    *
 *  it under the terms of the GNU Library General Public License as         *
 *  published by the Free Software Foundation; either version 2 of the      *
 *  License, or (at your option) any later version.                         *
 *                                                                          *
 *  This library is distributed in the hope that it will be useful, but     *
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT     *
 *  ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library        *
 *  General Public License for more details.                                *
 *                                                                          *
 *  You should have received a copy of the GNU Library General Public       *
 *  License along with this library; if not, write to the Free Foundation,  *
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA        *
 *                                                                          *
 ****************************************************************************/
#endregion

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;

namespace CoderBlu.Collections
{
	[Serializable]
	public class StringCollection : List<string>
	{
		public StringCollection ( )
			: base() {
		}
		public StringCollection ( int capacity )
			: base(capacity) {
		}
		public StringCollection ( IEnumerable<string> collection )
			: base(collection) {
		}

		protected StringCollection ( SerializationInfo info, StreamingContext context )
			: base(info, context) {
		}

		public string Concat ( int offset ) {
			return this.Concat(offset, ( this.Count - offset ));
		}
		public string Concat ( int offset, int count ) {
			if ( ( offset < 0 ) || ( offset >= this.Count ) )
				throw new ArgumentOutOfRangeException("offset");

			if ( ( count < 0 ) || ( count > ( this.Count - offset ) ) )
				throw new ArgumentOutOfRangeException("count");

			lock ( this._synclock ) {
				StringBuilder buffer = new StringBuilder(1024);

				for ( int s = offset, limit = ( offset + count ) ; s < limit ; s++ )
					buffer.Append(this [ s ]);

				return buffer.ToString();
			}
		}

		public string ConcatAll ( ) {
			return this.Concat(0, this.Count);
		}

		public StringCollection GetRange ( int offset ) {
			return this.GetRange(offset, ( this.Count - offset ));
		}
		public new StringCollection GetRange ( int offset, int count ) {
			return new StringCollection(base.GetRange(offset, count));
		}

		public string Join ( string separator ) {
			return this.Join(separator, 0);
		}
		public string Join ( string separator, int offset ) {
			return this.Join(separator, offset, ( this.Count - offset ));
		}
		public string Join ( string separator, int offset, int count ) {
			if ( ( offset < 0 ) || ( offset >= this.Count ) )
				throw new ArgumentOutOfRangeException("offset");

			if ( ( count < 0 ) || ( count > ( this.Count - offset ) ) )
				throw new ArgumentOutOfRangeException("count");

			lock ( this._synclock ) {
				StringBuilder buffer = new StringBuilder(1024);

				for ( int s = offset, limit = ( offset + count ) ; s < limit ; s++ ) {
					buffer.Append(this [ s ]);

					if ( s < ( limit - 1 ) )
						buffer.Append(separator);
				}

				return buffer.ToString();
			}
		}

		public StringCollection Match ( string pattern ) {
			return this.Match(pattern, RegexOptions.None);
		}
		public StringCollection Match ( string pattern, RegexOptions options ) {
			if ( String.IsNullOrEmpty(pattern) )
				throw new ArgumentNullException("pattern");

			return this.Match(new Regex(pattern, options));
		}
		public StringCollection Match ( Regex regex ) {
			if ( regex == null )
				throw new ArgumentNullException("regex");

			StringCollection collection = new StringCollection();

			lock ( this._synclock ) {
				for ( int s = 0 ; s < this.Count ; s++ ) {
					if ( regex.IsMatch(this [ s ]) )
						collection.Add(this [ s ]);
				}
			}

			return collection;
		}

		public void Replace ( string subject, string replacement ) {
			this.Replace(subject, replacement, 0, this.Count);
		}
		public void Replace ( string subject, string replacement, int offset, int count ) {
			if ( String.IsNullOrEmpty(subject) )
				throw new ArgumentNullException("subject");

			if ( ( offset < 0 ) || ( offset >= this.Count ) )
				throw new ArgumentOutOfRangeException("offset");

			if ( ( count < 0 ) || ( count > ( this.Count - offset ) ) )
				throw new ArgumentOutOfRangeException("count");

			if ( replacement == null )
				replacement = String.Empty;

			lock ( this._synclock ) {
				for ( int s = offset, limit = ( offset + count ) ; s < limit ; s++ ) {
					if ( String.Compare(this [ s ], subject) == 0 )
						this [ s ] = replacement;
				}
			}
		}
	}
}